package com.tmsps.ne4Weixin.action;

import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.tmsps.ne4Weixin.config.WxConfig;
import com.tmsps.ne4Weixin.message.in.InBaseMsg;
import com.tmsps.ne4Weixin.message.in.InTextMsg;
import com.tmsps.ne4Weixin.message.in.event.InClickEvent;
import com.tmsps.ne4Weixin.message.in.event.InFollowEvent;
import com.tmsps.ne4Weixin.message.in.event.InLocationEvent;
import com.tmsps.ne4Weixin.message.in.event.InQrCodeEvent;
import com.tmsps.ne4Weixin.utils.BeanUtil;
import com.tmsps.ne4Weixin.utils.StrUtil;
import com.tmsps.ne4Weixin.utils.WeixinUtil;
import com.tmsps.ne4Weixin.utils.XMLParser;

@Controller
public abstract class Ne4WeixinAction extends WeixinSupport {
	protected Logger log = LoggerFactory.getLogger(getClass());
	/**
	 * request and resopnse
	 */
	protected HttpServletRequest request;
	protected HttpServletResponse response;

	@ModelAttribute
	public void setRequestAndResopnse(HttpServletRequest request, HttpServletResponse response) {
		this.request = request;
		this.response = response;
	}
	//获取WxConfig
	public abstract WxConfig getWxConfig();

	@RequestMapping(method = RequestMethod.GET)
	protected final @ResponseBody String bind() {
		if (WeixinUtil.isCheck(request, getWxConfig().getToken())) {
			// 绑定微信服务器成功
			String echostr = request.getParameter("echostr");
			log.warn("bind weixin server success , and echostr is {}", echostr);
			return echostr;
		} else {
			// 绑定微信服务器失败
			log.warn("bind weixin server faile !!!");
			return "";
		}
	}

	@RequestMapping(method = RequestMethod.POST)
	protected final @ResponseBody String process(@RequestBody String body) {
		if (WeixinUtil.isCheck(request, getWxConfig().getToken())) {// 验证来自微信的消息
			log.debug("get message from weixin is {}", body);
			String msg = WeixinUtil.decryptMsg(request, getWxConfig(), body);
			log.debug("Express:{}", msg);
			Map<String, String> mxlMap = XMLParser.getXmlToMap(msg);
			log.debug("convert xml to map:{} ", mxlMap.toString());
			// 处理接收到的消息
			InBaseMsg msgBean = processInMsg(mxlMap);
			if (msgBean instanceof InTextMsg) {// 文本消息
				return processInTextMsg((InTextMsg) msgBean);
			} else if (msgBean instanceof InClickEvent) {// 点击菜单拉取消息时的事件推送
				return processInClickEvent((InClickEvent) msgBean);
			} else if (msgBean instanceof InLocationEvent) {// 地理位置上报信息
				return processInLocationEvent((InLocationEvent) msgBean);
			} else if (msgBean instanceof InFollowEvent) {// 处理关注，取消关注事件
				return processInFollowEvent((InFollowEvent) msgBean);
			} else if (msgBean instanceof InQrCodeEvent) {// 处理扫描二维码事件
				return processInQrCodeEvent((InQrCodeEvent) msgBean);
			} else {
				return processOtherEvent(msgBean);
			}
		}
		return null;
	}

	public InBaseMsg processInMsg(Map<String, String> mxlMap) {
		String msgType = StrUtil.isBlank(mxlMap.get("msgtype")) ? "" : mxlMap.get("msgtype");
		log.debug("msgType is {}", msgType);
		if ("text".equals(msgType)) {// 文本消息
			InTextMsg itMsg = BeanUtil.MapToBean(InTextMsg.class, mxlMap);
			return itMsg;
		}

		if ("event".equals(msgType)) {// 事件消息
			String Event = mxlMap.get("event");// 事件的Key
			log.debug("msgType is {} and Event is {}", msgType, Event);
			// 取消关注事件
			if (InFollowEvent.UNSUBSCRIBE.equals(Event)) {
				InFollowEvent msg = BeanUtil.MapToBean(InFollowEvent.class, mxlMap);
				return msg;
			}

			// 点击菜单拉取消息时的事件推送
			if (InClickEvent.CLICK.equals(Event)) {
				InClickEvent msg = BeanUtil.MapToBean(InClickEvent.class, mxlMap);
				return msg;
			}
			// 关注事件
			if (InFollowEvent.SUBSCRIBE.equals(Event) && StringUtils.isBlank(mxlMap.get("eventkey"))) {
				InFollowEvent msg = BeanUtil.MapToBean(InFollowEvent.class, mxlMap);
				return msg;
			}
			// 上报地址位置
			if (InLocationEvent.LOCATION.equals(Event)) {
				InLocationEvent msg = BeanUtil.MapToBean(InLocationEvent.class, mxlMap);
				return msg;
			}
			// 扫描二维码事件1, 未关注
			if (InQrCodeEvent.SCAN.equals(Event)) {
				InQrCodeEvent msg = BeanUtil.MapToBean(InQrCodeEvent.class, mxlMap);
				return msg;
			}
			// 扫描二维码事件2, 已经关注
			if (InQrCodeEvent.SUBSCRIBE.equals(Event) && !StringUtils.isBlank(mxlMap.get("eventkey"))) {
				InQrCodeEvent msg = BeanUtil.MapToBean(InQrCodeEvent.class, mxlMap);
				return msg;
			}
		}
		return null;
	}

	// 处理接收到的文本消息
	protected abstract String processInTextMsg(InTextMsg msg);
	
	//处理点击菜单拉取消息时的事件推送
	protected abstract String processInClickEvent(InClickEvent msgBean);

	// 处理地理位置上报消息
	protected abstract String processInLocationEvent(InLocationEvent msg);

	// 处理取消关注事件
	protected abstract String processInFollowEvent(InFollowEvent msg);

	// 处理扫描二维码事件
	protected abstract String processInQrCodeEvent(InQrCodeEvent msg);
	
	// 处理 其他 事件
	protected abstract String processOtherEvent(InBaseMsg msgBean);

}
